#pragma once
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <boost/algorithm/string.hpp>
#include "./cppjieba/include/cppjieba/Jieba.hpp"
#include <mutex>
#include <unordered_map>
// ifstream读文件，ofstream写文件(in和out)

namespace ns_util
{
    class FileUtil
    {
    public:
        static bool readFile(const std::string &filePath, std::string *outPut)
        {
            std::ifstream ifs(filePath, std::ios::in);
            if (!ifs.is_open())
            {
                std::cout << "open file failed!" << std::endl;
                return false;
            }

            std::string line;

            while (std::getline(ifs, line)) //从ifs流中一行一行读取
            {
                *outPut += line;
            }
            ifs.close();
            return true;
        }
    };

    class stringUtil
    {
    public:
        static void cutString(const std::string line, std::vector<std::string> *output, const std::string sep)
        {
            boost::split(*output, line, boost::is_any_of(sep), boost::token_compress_on);
        }
    };

    const char *const DICT_PATH = "./cppjieba/dict/jieba.dict.utf8";
    const char *const HMM_PATH = "./cppjieba/dict/hmm_model.utf8";
    const char *const USER_DICT_PATH = "./cppjieba/dict/user.dict.utf8";
    const char *const IDF_PATH = "./cppjieba/dict/idf.utf8";
    const char *const STOP_WORD_PATH = "./cppjieba/dict/stop_words.utf8";
    //单例+去暂停词
    class jieBaUtil
    {

    public:
        static void curString(const std::string &doc, std::vector<std::string> *output)
        {
            getInstance()->cutStringHelper(doc, output);
        }
        ~jieBaUtil()
        {
        }

        static jieBaUtil *getInstance()
        {
            std::mutex mtx;

            if (!_instance)
            {
                mtx.lock();
                if (!_instance)
                {
                    _instance=new jieBaUtil();

                    _instance->initjieBa();
                }
                mtx.unlock();
            }

            return _instance;
        }
        //此方法用于读取暂停词
        void initjieBa()
        {
            std::ifstream ifs(STOP_WORD_PATH, std::ios::in);

            if (!ifs.is_open())
            {
                return;
            }
            std::string line;

            while (getline(ifs, line))
            {
                stopWords.insert({line, true});
            }
            ifs.close();
        }
        //此方法将切分出的结果加入了去暂停词处理
        void cutStringHelper(const std::string &doc, std::vector<std::string> *output)
        {
            jieba.CutForSearch(doc, *output);
            for (auto it = output->begin(); it != output->end();)
            {
                if (stopWords.count(*it))
                {
                    it = output->erase(it);
                }
                else
                {
                    it++;
                }
            }
        }

    private:
        jieBaUtil() : jieba(DICT_PATH, HMM_PATH, USER_DICT_PATH, IDF_PATH, STOP_WORD_PATH)
        {
        }

        jieBaUtil(const jieBaUtil &) = delete;

        jieBaUtil &operator=(const jieBaUtil &) = delete;

        static jieBaUtil *_instance;

        std::unordered_map<std::string, bool> stopWords; //储存读取到的暂停词

        cppjieba::Jieba jieba;
    };

    jieBaUtil *jieBaUtil::_instance = nullptr;

} // namespace ns_util
